package com.newtouch.cq.base.starter.business.model;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.StrUtil;
import com.newtouch.cq.base.starter.business.entity.SysMenu;
import com.newtouch.cq.base.starter.business.model.vo.UserVO;
import com.newtouch.cq.lang.em.StatusEnum;
import com.newtouch.cq.lang.user.BaseUserDetails;
import lombok.*;
import lombok.experimental.Accessors;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ToString
public class UserDetailsImpl extends BaseUserDetails implements UserDetails {
	private static final long serialVersionUID = 1L;
	
	protected boolean isAdmin;
//	protected List<GrantedAuthority> userRoles;
	protected List<GrantedAuthority> authorities;
	protected List<String> userPermissions;
//	protected List<String> userRoles;
//	protected List<MenuTreeModelPm> accessMenus;
//	protected List<RouteTreeModelPm> accessRoutes;
	protected boolean accountNonExpired;
	protected boolean accountNonLocked;
	protected boolean credentialsNonExpired;
	protected boolean enabled;

	public UserDetailsImpl(UserVO userVO, List<? extends SysMenu> menus) {
		
		BeanUtil.copyProperties(userVO, this, CopyOptions.create().setIgnoreNullValue(true));

		authorities = new ArrayList<>(menus.size());
//        userPermissions = new ArrayList<>(menuList.size());
//        userRoles = new ArrayList<>(roleList.size());
//		if(CollectionUtil.isNotEmpty(userVO.getRoleList())) {
//			userVO.getRoleList().stream().filter(role -> StrUtil.isNotBlank(role.getRoleCode())).forEach(role -> {
//				userRoles.add(role.getRoleCode());
//			});
//		}
//        accessMenus = new ArrayList<>();
//        accessRoutes = new ArrayList<>();
//        List<RouteTreeModelPm> accessRoutesChildren = new ArrayList<>();

//		this.avatarUrl = userVO.getAvatar();
		isAdmin = id == 1;
		accountNonExpired = true;
		accountNonLocked = StatusEnum.VALID == userVO.getStatus();
		credentialsNonExpired = true;
		enabled = StatusEnum.VALID ==  status;
//		menuList.sort(Comparator.comparing(e -> e.getSort()));
		menus.stream().forEach(menu -> {
			if(StrUtil.isNotEmpty(menu.getPermission())) {
				authorities.add(new CustomGrantedAuthority().setAuthority(menu.getPermission()));
//				userPermissions.add(menu.getPermission());
			}
//			if(menu.getType() == MenuTypeEnum.MENU) {
//				MenuTreeModelPm pm = new MenuTreeModelPm(menu);
//				accessMenus.add(pm);
//				if(!StrUtil.equalsIgnoreCase(menu.getComponent(), "Layout")) {
//					RouteTreeModelPm route = new RouteTreeModelPm(menu);
//					accessRoutesChildren.add(route);
//				}
//			}
		});
//		accessMenus = TreeUtilParentAble.buildTree(accessMenus);
//		RouteTreeModelPm top = new RouteTreeModelPm();
//		top.setName("index");
//		top.setPath("/");
//		top.setChildren(accessRoutesChildren);
//		accessRoutes.add(top);
//		accessRoutes = TreeUtilParentAble.buildTree(accessRoutes);
	}

	@Override
	public List<GrantedAuthority> getAuthorities() {
		return authorities;
	}

	public UserDetailsImpl setId(Long id) {
		this.id = id;
		return this;
	}
	public UserDetailsImpl setUsername(String username) {
		this.username = username;
		return this;
	}
	public UserDetailsImpl setPassword(String password) {
		this.password = password;
		return this;
	}
	public UserDetailsImpl setSalt(String salt) {
		this.salt = salt;
		return this;
	}
	public UserDetailsImpl setStatus(StatusEnum status) {
		this.status = status;
		return this;
	}
//	public UserDetailsImpl setLabel(String label) {
//		this.label = label;
//		return this;
//	}
	public UserDetailsImpl setOrgId(long orgId) {
		this.orgId = orgId;
		return this;
	}
//	public UserDetailsImpl setCreateTime(Date createTime) {
//		this.createTime = createTime;
//		return this;
//	}
//	public UserDetailsImpl setUpdateTime(Date updateTime) {
//		this.updateTime = updateTime;
//		return this;
//	}
//	public UserDetailsImpl setDelFlag(String delFlag) {
//		this.delFlag = delFlag;
//		return this;
//	}
	public UserDetailsImpl setOrgIdList(List<Long> orgIdList) {
		this.orgIdList = orgIdList;
		return this;
	}
//	public UserDetailsImpl setRoleList(List<SysRoleVo> roleList) {
//		this.roleList = roleList;
//		return this;
//	}
	
	@SuppressWarnings("serial")
	@Getter
	@Setter
	@ToString
	@Accessors(chain=true)
	private static class CustomGrantedAuthority implements GrantedAuthority, Serializable {
		protected String authority;
	}

}
